Take Home Exercise 3

A short description of the post.

Toh Jun Long https://linkedin.com/in/tohjunlong
11-01-2021

1.0.0 Context and analysis goal(s):

1.1.o Contexts Housing is an essential component of household wealth worldwide. Buying a housing has always been a major investment for most people. The price of housing is affected by many factors. Some of them are global in nature such as the general economy of a country or inflation rate. Others can be more specific to the properties themselves. These factors can be further divided to structural and locational factors. Structural factors are variables related to the property themselves such as the size, fitting, and tenure of the property. Locational factors are variables related to the neighbourhood of the properties such as proximity to childcare centre, public transport service and shopping centre.

Hedonic pricing model is used to examine the effect of housing factors as discussed above on the price. Conventional, this model was built by using Ordinary Least Square (OLS) method. However, this method failed to take into consideration that spatial autocorrelation and spatial heterogeneity exist in geographic data sets such as housing transactions. With the existence of spatial autocorrelation, the OLS estimation of hedonic pricing models could lead to biased, inconsistent, or inefficient results (Anselin 1998). In view of this limitation, Geographical Weighted Regression (GWR) was introduced for calibrating hedonic price model for housing.

1.2.1 Exploratory Spatial Data Analysis

In this take-home exercise, we need to build a hedonic pricing models to explain factors affecting the resale prices of public housing in Singapore. The hedonic price models must be built by using appropriate GWR methods.

  1. Understanding the Dataset

2.1 Resale flat

Datas: Aspatial + Resale flat prices based on registration date from jan 2017 onwards. + hawker centres + supermarkets Sources: + https://data.gov.sg/dataset/resale-flat-prices + https://www.onemap.gov.sg/docs/

Geospatial + Train Stations: MRTLRTStnPtt.shp + Singapore Planning Subzones: MP14_SUBZONE_WEB_PL.shp

Sources: + http://insideairbnb.com/get-the-data.html + https://cran.r-project.org/web/packages/onemapsgapi/index.html + https://datamall.lta.gov.sg/content/datamall/en/search_datasets.html?searchText=mrt%20stations

  1. Importing Required Packages
packages = c("maptools","sf","raster","spatstat","tmap","tidyverse", 'sp','olsrr', 'corrplot', 'ggpubr', 'spdep', 'GWmodel','httr','jsonlite','nngeo','stringr')
for(p in packages){
  if(!require(p, character.only = T)){
      install.packages(p)
  }
  library(p,character.only = T)
}
  1. Retrieving data from OneMap API

4.1.1 Supermarket

queryName = "supermarkets"
supermarketUrl = paste(c(url,"?queryName=",queryName, "&token=",token),collapse = "")
supermarketUrl
[1] "https://developers.onemap.sg/privateapi/themesvc/retrieveTheme?queryName=supermarkets&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjc5NDgsInVzZXJfaWQiOjc5NDgsImVtYWlsIjoianVubG9uZy50b2guMjAxOUBzbXUuZWR1LnNnIiwiZm9yZXZlciI6ZmFsc2UsImlzcyI6Imh0dHA6XC9cL29tMi5kZmUub25lbWFwLnNnXC9hcGlcL3YyXC91c2VyXC9zZXNzaW9uIiwiaWF0IjoxNjM2MjYzNTcwLCJleHAiOjE2MzY2OTU1NzAsIm5iZiI6MTYzNjI2MzU3MCwianRpIjoiNzU4YjQ3NjE3YWYwM2E5NzhjY2RiYmUzMGQ2ZjRlNjcifQ.CW1QqnmI-_0Z_wxwAylq0hOCdTkNsh1Nnin4c2yNR2g"
resp = GET(supermarketUrl)
supermarkets = fromJSON(rawToChar(resp$content))
supermarkets = do.call("rbind", supermarkets)
supermarkets = supermarkets[c(6,7,8,9,10,11,12,13)]
supermarkets = supermarkets[-1,]
rownames(supermarkets) = 1:nrow(supermarkets)
glimpse(supermarkets)
Rows: 526
Columns: 8
$ NAME        <chr> "LI LI CHENG SUPERMARKET (PUNGGOL) PTE. LTD.", "~
$ DESCRIPTION <chr> "NE12I65N000", "E73010V000", "NE11909C000", "S02~
$ BLK_HOUSE   <chr> "273C", "11", "683", "631", "201B", "201D", "421~
$ STR_NAME    <chr> "PUNGGOL PLACE", "UPPER BOON KENG ROAD", "HOUGAN~
$ UNIT_NO     <chr> "884", "901", "903", "954", "1091", "1161", "116~
$ POSTCODE    <chr> "823273", "380011", "530683", "470631", "522201"~
$ LatLng      <chr> "1.40230300615945,103.901262393433", "1.31423937~
$ ICON_NAME   <chr> "supermarketlogo.jpg", "supermarketlogo.jpg", "s~

4.1.2 Hawker Centres

queryName = "hawkercentre"
hawkerCentresUrl = paste(c(url,"?queryName=",queryName, "&token=",token),collapse = "")
hawkerCentresUrl
[1] "https://developers.onemap.sg/privateapi/themesvc/retrieveTheme?queryName=hawkercentre&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjc5NDgsInVzZXJfaWQiOjc5NDgsImVtYWlsIjoianVubG9uZy50b2guMjAxOUBzbXUuZWR1LnNnIiwiZm9yZXZlciI6ZmFsc2UsImlzcyI6Imh0dHA6XC9cL29tMi5kZmUub25lbWFwLnNnXC9hcGlcL3YyXC91c2VyXC9zZXNzaW9uIiwiaWF0IjoxNjM2MjYzNTcwLCJleHAiOjE2MzY2OTU1NzAsIm5iZiI6MTYzNjI2MzU3MCwianRpIjoiNzU4YjQ3NjE3YWYwM2E5NzhjY2RiYmUzMGQ2ZjRlNjcifQ.CW1QqnmI-_0Z_wxwAylq0hOCdTkNsh1Nnin4c2yNR2g"
resp = GET(hawkerCentresUrl)
hawkerCentres = fromJSON(rawToChar(resp$content))
hawkerCentres = do.call("rbind", hawkerCentres)
hawkerCentres = hawkerCentres[c(6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22)]
hawkerCentres = hawkerCentres[-1,]
rownames(hawkerCentres) = 1:nrow(hawkerCentres)
glimpse(hawkerCentres)
Rows: 125
Columns: 17
$ NAME                         <chr> "Bedok Reservoir Road Blk 630",~
$ DESCRIPTION                  <chr> "HUP Rebuilding", "HUP Standard~
$ ADDRESSBLOCKHOUSENUMBER      <chr> "630", "16", "29", "38A", "166"~
$ ADDRESSPOSTALCODE            <chr> "470630", "460016", "330029", "~
$ ADDRESSSTREETNAME            <chr> "Bedok Reservoir Road", "Bedok ~
$ PHOTOURL                     <chr> "http://www.nea.gov.sg/images/d~
$ LANDXADDRESSPOINT            <chr> "36985", "39376.14", "31305.63"~
$ LANDYADDRESSPOINT            <chr> "35039.64", "33645.7", "33497.8~
$ EST_ORIGINAL_COMPLETION_DATE <chr> "30/6/1982", "12/5/1975", "17/3~
$ STATUS                       <chr> "Existing", "Existing", "Existi~
$ ADDRESSTYPE                  <chr> "I", "I", "I", "I", "I", "I", "~
$ HUP_COMPLETION_DATE          <chr> "28/2/2006", "20/9/2012", "31/1~
$ ADDRESS_MYENV                <chr> "Blk 630, Bedok Reservoir Road,~
$ LatLng                       <chr> "1.33315924777343,103.914053888~
$ ICON_NAME                    <chr> "HC icons_Opt 8.jpg", "HC icons~
$ APPROXIMATE_GFA              <chr> NA, NA, NA, "1733.074", "2568.9~
$ INFO_ON_CO_LOCATORS          <chr> NA, NA, NA, NA, NA, NA, NA, NA,~

Saving to csv in local machine for future uses:

write.csv(supermarkets,"data/aspatial/supermarkets.csv",row.names = FALSE)
write.csv(hawkerCentres,"data/aspatial/hawkercentres.csv",row.names = FALSE)
  1. Importing datas

5.1 importing Geospatial data

5.1.1. importing train station shp file

train_station = st_read(dsn = "data/geospatial",
                        layer = "MRTLRTStnPtt")
Reading layer `MRTLRTStnPtt' from data source 
  `C:\JunLonggggg\IS415\junlong-is415\_posts\2021-11-01-take-home-exercise-3\data\geospatial' 
  using driver `ESRI Shapefile'
Simple feature collection with 171 features and 3 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 6138.311 ymin: 27555.06 xmax: 45254.86 ymax: 47854.2
Projected CRS: SVY21
st_crs(train_station)
Coordinate Reference System:
  User input: SVY21 
  wkt:
PROJCRS["SVY21",
    BASEGEOGCRS["SVY21[WGS84]",
        DATUM["World Geodetic System 1984",
            ELLIPSOID["WGS 84",6378137,298.257223563,
                LENGTHUNIT["metre",1]],
            ID["EPSG",6326]],
        PRIMEM["Greenwich",0,
            ANGLEUNIT["Degree",0.0174532925199433]]],
    CONVERSION["unnamed",
        METHOD["Transverse Mercator",
            ID["EPSG",9807]],
        PARAMETER["Latitude of natural origin",1.36666666666667,
            ANGLEUNIT["Degree",0.0174532925199433],
            ID["EPSG",8801]],
        PARAMETER["Longitude of natural origin",103.833333333333,
            ANGLEUNIT["Degree",0.0174532925199433],
            ID["EPSG",8802]],
        PARAMETER["Scale factor at natural origin",1,
            SCALEUNIT["unity",1],
            ID["EPSG",8805]],
        PARAMETER["False easting",28001.642,
            LENGTHUNIT["metre",1],
            ID["EPSG",8806]],
        PARAMETER["False northing",38744.572,
            LENGTHUNIT["metre",1],
            ID["EPSG",8807]]],
    CS[Cartesian,2],
        AXIS["(E)",east,
            ORDER[1],
            LENGTHUNIT["metre",1,
                ID["EPSG",9001]]],
        AXIS["(N)",north,
            ORDER[2],
            LENGTHUNIT["metre",1,
                ID["EPSG",9001]]]]

Reading in the Planning Subzone Geospatial data.

mpsz = st_read(dsn = "data/geospatial",
               layer = "MP14_SUBZONE_WEB_PL")
Reading layer `MP14_SUBZONE_WEB_PL' from data source 
  `C:\JunLonggggg\IS415\junlong-is415\_posts\2021-11-01-take-home-exercise-3\data\geospatial' 
  using driver `ESRI Shapefile'
Simple feature collection with 323 features and 15 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 2667.538 ymin: 15748.72 xmax: 56396.44 ymax: 50256.33
Projected CRS: SVY21
st_crs(mpsz)
Coordinate Reference System:
  User input: SVY21 
  wkt:
PROJCRS["SVY21",
    BASEGEOGCRS["SVY21[WGS84]",
        DATUM["World Geodetic System 1984",
            ELLIPSOID["WGS 84",6378137,298.257223563,
                LENGTHUNIT["metre",1]],
            ID["EPSG",6326]],
        PRIMEM["Greenwich",0,
            ANGLEUNIT["Degree",0.0174532925199433]]],
    CONVERSION["unnamed",
        METHOD["Transverse Mercator",
            ID["EPSG",9807]],
        PARAMETER["Latitude of natural origin",1.36666666666667,
            ANGLEUNIT["Degree",0.0174532925199433],
            ID["EPSG",8801]],
        PARAMETER["Longitude of natural origin",103.833333333333,
            ANGLEUNIT["Degree",0.0174532925199433],
            ID["EPSG",8802]],
        PARAMETER["Scale factor at natural origin",1,
            SCALEUNIT["unity",1],
            ID["EPSG",8805]],
        PARAMETER["False easting",28001.642,
            LENGTHUNIT["metre",1],
            ID["EPSG",8806]],
        PARAMETER["False northing",38744.572,
            LENGTHUNIT["metre",1],
            ID["EPSG",8807]]],
    CS[Cartesian,2],
        AXIS["(E)",east,
            ORDER[1],
            LENGTHUNIT["metre",1,
                ID["EPSG",9001]]],
        AXIS["(N)",north,
            ORDER[2],
            LENGTHUNIT["metre",1,
                ID["EPSG",9001]]]]

Setting the projected coordinate system to Singapore’s standard projection system of 3414.

train_station_3414 = st_set_crs(train_station, 3414)
mpsz_3414 = st_set_crs(mpsz, 3414)

To check if the change is successful:

st_crs(train_station_3414)
Coordinate Reference System:
  User input: EPSG:3414 
  wkt:
PROJCRS["SVY21 / Singapore TM",
    BASEGEOGCRS["SVY21",
        DATUM["SVY21",
            ELLIPSOID["WGS 84",6378137,298.257223563,
                LENGTHUNIT["metre",1]]],
        PRIMEM["Greenwich",0,
            ANGLEUNIT["degree",0.0174532925199433]],
        ID["EPSG",4757]],
    CONVERSION["Singapore Transverse Mercator",
        METHOD["Transverse Mercator",
            ID["EPSG",9807]],
        PARAMETER["Latitude of natural origin",1.36666666666667,
            ANGLEUNIT["degree",0.0174532925199433],
            ID["EPSG",8801]],
        PARAMETER["Longitude of natural origin",103.833333333333,
            ANGLEUNIT["degree",0.0174532925199433],
            ID["EPSG",8802]],
        PARAMETER["Scale factor at natural origin",1,
            SCALEUNIT["unity",1],
            ID["EPSG",8805]],
        PARAMETER["False easting",28001.642,
            LENGTHUNIT["metre",1],
            ID["EPSG",8806]],
        PARAMETER["False northing",38744.572,
            LENGTHUNIT["metre",1],
            ID["EPSG",8807]]],
    CS[Cartesian,2],
        AXIS["northing (N)",north,
            ORDER[1],
            LENGTHUNIT["metre",1]],
        AXIS["easting (E)",east,
            ORDER[2],
            LENGTHUNIT["metre",1]],
    USAGE[
        SCOPE["Cadastre, engineering survey, topographic mapping."],
        AREA["Singapore - onshore and offshore."],
        BBOX[1.13,103.59,1.47,104.07]],
    ID["EPSG",3414]]
tm_shape(mpsz_3414) + 
  tm_polygons() +
tm_shape(train_station_3414)+
  tm_dots(alpha = 0.5,
          size = 0.125)

Reading in the Aspatial data.

Resale Flats Data:

Adding lat lng:

resale = read_csv("data/aspatial/resale-flat-prices-based-on-registration-date-from-jan-2017-onwards.csv")
glimpse(resale)
  1. Data Wrangling

6.1 Formating geometric attributes

6.1.1 Splitting LatLng of supermarkets and Hawker Centres

supermarkets = supermarkets %>% separate(LatLng,c("Latitude","Longitude"),",")
hawkerCentres = hawkerCentres %>% separate(LatLng,c("Latitude","Longitude"),",")

6.1.2 Assigning spatial projection system of supermarkets and Hawker Centres to 3414

supermarkets_3414 = st_as_sf(supermarkets,
                          coords = c("Longitude","Latitude"),
                          crs = 4326) %>% 
  st_transform(crs = 3414)
hawkerCentres_3414 = st_as_sf(hawkerCentres,
                          coords = c("Longitude","Latitude"),
                          crs = 4326) %>% 
  st_transform(crs = 3414)

6.1.3 Associating geospatial property to resale flat data

resale["Latitude"] = NA
resale["Longitude"] = NA
sorted_resale_by_town = resale[order(resale$town),]
url = "https://developers.onemap.sg/commonapi/search"

for (row in 1:nrow(resale)){
  print(row)
  searchVal = paste(sorted_resale_by_town[row,'block'], sorted_resale_by_town[row,'street_name'])
  query = list('searchVal' = searchVal, 'returnGeom' = "Y", 'getAddrDetails' ="N")
  resp = GET(url, query = query, verbose())
  sorted_resale_by_town$Latitude[row] = content(resp)$results[[1]]$LATITUDE
  sorted_resale_by_town$Longitude[row] = content(resp)$results[[1]]$LONGITUDE
}
write.csv(sorted_resale_by_town,"data/aspatial/resale.csv",row.names = FALSE)

Read completed resale file:

resale = read_csv("data/aspatial/resale.csv")
glimpse(resale)
Rows: 15,901
Columns: 15
$ month                <chr> "2019-01", "2019-01", "2019-01", "2019-~
$ town                 <chr> "ANG MO KIO", "ANG MO KIO", "ANG MO KIO~
$ flat_type            <chr> "4 ROOM", "4 ROOM", "4 ROOM", "4 ROOM",~
$ address              <chr> "204 ANG MO KIO AVE 3", "175 ANG MO KIO~
$ block                <chr> "204", "175", "543", "118", "411", "546~
$ street_name          <chr> "ANG MO KIO AVE 3", "ANG MO KIO AVE 4",~
$ storey_range         <chr> "01 TO 03", "07 TO 09", "01 TO 03", "04~
$ floor_area_sqm       <dbl> 92, 91, 92, 99, 92, 92, 92, 92, 93, 91,~
$ flat_model           <chr> "New Generation", "New Generation", "Ne~
$ lease_commence_date  <dbl> 1977, 1981, 1981, 1978, 1979, 1981, 197~
$ remaining_lease      <chr> "57 years", "61 years 06 months", "61 y~
$ remaininglease_years <dbl> 57.00, 61.50, 61.08, 58.33, 59.58, 61.0~
$ resale_price         <dbl> 330000, 360000, 370000, 375000, 380000,~
$ LATITUDE             <dbl> 1.367368, 1.375723, 1.374301, 1.373296,~
$ LONGITUDE            <dbl> 103.8439, 103.8371, 103.8562, 103.8355,~
resale_3414 = st_as_sf(resale,
                          coords = c("LONGITUDE","LATITUDE"),
                          crs = 4326) %>% 
  st_transform(crs = 3414)
tm_shape(mpsz_3414) +
  tm_polygons() +
tm_shape(resale_3414)+
  tm_dots(alpha = 0.5,
          size = 0.125)

resale_3414["prx_to_hawker"] = NA
resale_3414["prx_to_trainStn"] = NA
resale_3414["prx_to_supermarket"] = NA
prox_hawker = unlist(st_nn(resale_3414[1:nrow(resale_3414),], hawkerCentres_3414,k =1, returnDist = TRUE)[[2]])
resale_3414 <- resale_3414 %>%
  mutate(`prx_to_hawker` = unlist(st_nn(resale_3414[1:nrow(resale_3414),], hawkerCentres_3414,k =1, returnDist = TRUE)[[2]])) %>% 
    mutate(`prx_to_trainStn` = unlist(st_nn(resale_3414[1:nrow(resale_3414),], train_station_3414,k =1, returnDist = TRUE)[[2]])) %>% 
  mutate(`prx_to_supermarket` = unlist(st_nn(resale_3414[1:nrow(resale_3414),], supermarkets_3414,k =1, returnDist = TRUE)[[2]]))
  1. EDA
ggplot(data=resale_3414, aes(x=`resale_price`)) +
  geom_histogram(bins=20, color="black", fill="light blue")

resale_3414 <- resale_3414 %>%
  mutate(`log_resale_price` = log(resale_price))
resale_3414 <- resale_3414 %>%
  mutate(`max_floor` = as.numeric(str_sub(resale_3414$storey_range,-1)))
resale_3414$floor_area_sqm = as.numeric(resale_3414$floor_area_sqm)
AREA_SQM <- ggplot(data=resale_3414, aes(x= `floor_area_sqm`)) +
  geom_histogram(bins=20, color="black", fill="light blue")
FLOOR_LVL <- ggplot(data=resale_3414, aes(x= `max_floor`)) +
  geom_histogram(bins=20, color="black", fill="light blue")
REMAINING_LEASE <- ggplot(data=resale_3414, aes(x= `remaininglease_years`)) +
  geom_histogram(bins=20, color="black", fill="light blue")
PROX_HAWKER = ggplot(data=resale_3414, aes(x=`prx_to_hawker`)) +
  geom_histogram(bins=20, color="black", fill="light blue")
PROX_TRAINSTN = ggplot(data=resale_3414, aes(x=`prx_to_trainStn`)) +
  geom_histogram(bins=20, color="black", fill="light blue")
PROX_SUPERMARKET = ggplot(data=resale_3414, aes(x=`prx_to_supermarket`)) +
  geom_histogram(bins=20, color="black", fill="light blue")

ggarrange(AREA_SQM, FLOOR_LVL, REMAINING_LEASE, PROX_HAWKER, PROX_TRAINSTN, PROX_SUPERMARKET,  ncol = 3, nrow = 4)

tm_shape(mpsz_3414)+
  tm_polygons() +
tm_shape(resale_3414) +  
  tm_dots(col = "resale_price",
          alpha = 0.6,
          style="quantile") +
  tm_view(set.zoom.limits = c(11,14))

  1. Hedonic Price Modelling

8.1 Simple linear regression

resale_3414.slr <- lm(formula=resale_price ~ floor_area_sqm, data = resale_3414)
summary(resale_3414.slr)

Call:
lm(formula = resale_price ~ floor_area_sqm, data = resale_3414)

Residuals:
    Min      1Q  Median      3Q     Max 
-220690  -79631  -28690   36291  751169 

Coefficients:
               Estimate Std. Error t value Pr(>|t|)    
(Intercept)    527814.2    12779.7  41.301  < 2e-16 ***
floor_area_sqm   -990.3      133.9  -7.394  1.5e-13 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 119900 on 15899 degrees of freedom
Multiple R-squared:  0.003426,  Adjusted R-squared:  0.003364 
F-statistic: 54.67 on 1 and 15899 DF,  p-value: 1.5e-13

The output can be formulated into:

y = 527814.2 - 990.3 x floor_area_sqm

The r-square value is 0.003426, which is signify that this formula is not a good gauge as the formula is only able to explain 0.3% of the data.

However, the hypothesis testing with p-value much lower than 0.0001 suggest that we can confidently reject the null hypothesis that mean is a good estimator of resale_price and that the simple linear regression model above is a poor estimator for resale_price

Both the coefficients have a p-value less than 0.0001 as well, thus we can confidently reject the null hypothesis that B0 and B1 are equal to 0, meaning that both B0 and B1 are good parameter estimates.

ggplot(data=resale_3414,  
       aes(x=`floor_area_sqm`, y=`resale_price`)) +
  geom_point() +
  geom_smooth(method = lm)

This shows that the relationship between floor_area_sqm and resale_price might not be able to approximate to a linear relationship.

8.2 Multiple Linear Regression

resale_tbl = as_tibble(resale_3414)
corrplot(cor(resale_tbl[, c("remaininglease_years","prx_to_hawker","prx_to_trainStn","prx_to_supermarket","max_floor","floor_area_sqm")]),
         tl.pos = "td", tl.cex = 0.5, method = "number", type = "upper")

From the plot above, we can see that none of the independent variable are highly correlated to each other, therefore, we can use the variables.

resale_tbl.mlr <- lm(formula = resale_price ~ remaininglease_years + floor_area_sqm  + max_floor + prx_to_hawker + prx_to_trainStn  + prx_to_supermarket, data=resale_3414)
summary(resale_tbl.mlr)

Call:
lm(formula = resale_price ~ remaininglease_years + floor_area_sqm + 
    max_floor + prx_to_hawker + prx_to_trainStn + prx_to_supermarket, 
    data = resale_3414)

Residuals:
    Min      1Q  Median      3Q     Max 
-197602  -72132  -21827   40103  674490 

Coefficients:
                       Estimate Std. Error t value Pr(>|t|)    
(Intercept)          142113.774  13753.774  10.333   <2e-16 ***
remaininglease_years   3262.168     67.431  48.378   <2e-16 ***
floor_area_sqm         1371.386    121.423  11.294   <2e-16 ***
max_floor                60.417    315.951   0.191    0.848    
prx_to_hawker           -68.923      1.649 -41.790   <2e-16 ***
prx_to_trainStn         -47.715      2.200 -21.693   <2e-16 ***
prx_to_supermarket      -45.759      5.454  -8.390   <2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 104400 on 15894 degrees of freedom
Multiple R-squared:  0.2455,    Adjusted R-squared:  0.2452 
F-statistic: 861.8 on 6 and 15894 DF,  p-value: < 2.2e-16

From the statistical summary, we can see that not all variables are statistically significant, thus we will need to revise the model by removing these statistically insignificant variables. Namely: * max_floor

resale_tbl.mlr1 <- lm(formula = resale_price ~ remaininglease_years + floor_area_sqm + prx_to_hawker + prx_to_trainStn  + prx_to_supermarket, data=resale_3414)
ols_regress(resale_tbl.mlr1)
                             Model Summary                              
-----------------------------------------------------------------------
R                       0.495       RMSE                    104356.809 
R-Squared               0.245       Coef. Var                   24.068 
Adj. R-Squared          0.245       MSE                10890343642.219 
Pred R-Squared          0.245       MAE                      77678.476 
-----------------------------------------------------------------------
 RMSE: Root Mean Square Error 
 MSE: Mean Square Error 
 MAE: Mean Absolute Error 

                                      ANOVA                                       
---------------------------------------------------------------------------------
                    Sum of                                                       
                   Squares           DF        Mean Square       F          Sig. 
---------------------------------------------------------------------------------
Regression    5.631684e+13            5       1.126337e+13    1034.253    0.0000 
Residual       1.73102e+14        15895    10890343642.219                       
Total         2.294188e+14        15900                                          
---------------------------------------------------------------------------------

                                             Parameter Estimates                                               
--------------------------------------------------------------------------------------------------------------
               model          Beta    Std. Error    Std. Beta       t        Sig          lower         upper 
--------------------------------------------------------------------------------------------------------------
         (Intercept)    142448.724     13641.365                  10.442    0.000    115710.103    169187.345 
remaininglease_years      3262.077        67.428        0.349     48.379    0.000      3129.912      3394.243 
      floor_area_sqm      1371.204       121.416        0.081     11.293    0.000      1133.215      1609.193 
       prx_to_hawker       -68.919         1.649       -0.296    -41.793    0.000       -72.151       -65.687 
     prx_to_trainStn       -47.719         2.199       -0.153    -21.697    0.000       -52.030       -43.408 
  prx_to_supermarket       -45.747         5.453       -0.060     -8.389    0.000       -56.437       -35.058 
--------------------------------------------------------------------------------------------------------------

Assumptions of linear regression models

  1. Linearity Assumption: Relationship between dependent and independent variables is (approximately) linear.

  2. Normality Assumption: The residual errors are assumed to be normally distributed.

  3. Homogenuity of residual variance: The residuals are assumed to have a constant variance (homoscedasticity).

  4. Residuals are independent to each other

  5. (Optional) Errors are normally distributed with a population mean of 0.

Checking for multicollinearity

We will explore the use of olsrr, a package specially programmed for performing Ordinary Least Squared (OLS) regression.

Some of the useful methods includes: * comprehensive regression output * residual diagnostics * measures of influence * heteroskedasticity tests * collinearity diagnostics * model fit assessment * variable contribution assessment * variable selection procedures

We will be using ols_vid_tol() method from olsrr package for multicollinearity.

ols_vif_tol(resale_tbl.mlr1)
             Variables Tolerance      VIF
1 remaininglease_years 0.9130828 1.095191
2       floor_area_sqm 0.9215493 1.085129
3        prx_to_hawker 0.9462454 1.056808
4      prx_to_trainStn 0.9508515 1.051689
5   prx_to_supermarket 0.9301457 1.075100

A good judgement of multicollinearity would be if the VIF is above 10. Since none of the variables exceed the VIF value of 10, we can safely conclude that there are no sign of multicollinearity among the independent variables.

Testing for non-linearity

In multiple linear regression, we need to test for linearity and additivity of the relationship between dependent and independent variables. We can do so using ols_plot_resid_fit() from olsrr package to perform linearity assumption test.

ols_plot_resid_fit(resale_tbl.mlr1)

From the figure above, we can see that the residual roughly revolves around the 0 line, thus we can safely conclude that the relationships between the dependent and the independent variables are linear.

Testing for normality assumption

Next, we still need to test if the residual errors are normally distributed using ols_plot_resid_hist() to perform normality assumption test.

ols_plot_resid_hist(resale_tbl.mlr1)

The figure above shows that the residual of the multiple linear regression model resemble a rather flat normal distribution.

Testing for Spatial Autocorrelation

The hedonic model we are building are using geographically referenced attribute, thus we should visualize the residual of the hedonic pricing model.

To perform spatial autocorrelation test, we will have to convert condo_resale.sf into SpatialPointDataFrame.

mlr.output <- as.data.frame(resale_tbl.mlr1$residuals)

Joining the newly created data frame with condo_resale.sf

resale_tbl.res.sf <- cbind(resale_3414, 
                        resale_tbl.mlr1$residuals) %>%
rename(`MLR_RES` = `resale_tbl.mlr1.residuals`)

Converting the sf object into SpatialPointDataFrame using spdep package:

resale_tbl.sp <- as_Spatial(resale_tbl.res.sf)
resale_tbl.sp
class       : SpatialPointsDataFrame 
features    : 15901 
extent      : 11597.31, 42623.63, 28217.39, 48741.06  (xmin, xmax, ymin, ymax)
crs         : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 
variables   : 19
names       :   month,       town, flat_type,          address, block,   street_name, storey_range, floor_area_sqm,    flat_model, lease_commence_date,    remaining_lease, remaininglease_years, resale_price,    prx_to_hawker,  prx_to_trainStn, ... 
min values  : 2019-01, ANG MO KIO,    4 ROOM,   1 CHAI CHEE RD,     1,  ADMIRALTY DR,     01 TO 03,             74, Adjoined flat,                1967, 45 years 06 months,                 45.5,       218000, 33.3358643817954, 22.0407324774434, ... 
max values  : 2020-09,     YISHUN,    4 ROOM, 9B BOON TIONG RD,    9B, YUNG SHENG RD,     49 TO 51,            138,       Type S1,                2018,           97 years,                   97,      1186888, 2867.63031236184, 2130.60636038504, ... 

Now we can plot a interactive visualization of the residual on a map itself.

First, setting the tmap mode to “view”, or interactive.

tmap_mode("view")

Plotting the geographically referenced residual:

tmap_options(check.and.fix = TRUE) 
tm_shape(mpsz_3414)+
  tm_polygons(alpha = 0.4) +
tm_shape(resale_tbl.res.sf) +  
  tm_dots(col = "MLR_RES",
          alpha = 0.6,
          style="quantile") +
  tm_view(set.zoom.limits = c(11,14))

Setting back the tmap mode to “plot”:

tmap_mode("plot")

The above plot does show signs of spatial autocorrelation since there are some parts with concentrated high MLR_RES values, however, to be more definitive, we will use Moran’s I test to confirm our observation.

First, computing the distance-based weight matrix using dnearneigh() function of spdep:

nb <- dnearneigh(coordinates(resale_tbl.sp), 0, 1500, longlat = FALSE)
summary(nb)
Neighbour list object:
Number of regions: 15901 
Number of nonzero links: 10219360 
Percentage nonzero weights: 4.0418 
Average number of links: 642.6866 
Link number distribution:

   2    7   14   25   26   31   32   46   56   57   60   65   68   69 
   3    1   14   15    5    4    2   47    4    4    5    2    4    1 
  71   72   75   79   86   88   89   90   97   99  101  103  106  109 
  12    1    1   78    3    5    4    3    8    8    6    2    2    5 
 110  112  115  117  118  119  120  121  122  123  124  125  126  128 
   8    3    6    1    9    6    5    7    4   22    7   55   21   30 
 130  131  132  133  134  135  136  137  138  139  140  141  142  143 
   1   14    6   14    7    5    5    9    2   28    4    2    8   15 
 145  146  147  148  149  150  151  152  153  154  155  156  157  158 
   9    6   17    6    1    1   21   20   13    7    3    8    9    5 
 159  160  161  162  163  164  165  166  167  168  169  170  171  173 
  17    6    3    2   12    6    6    3   11    3   11    3    8   14 
 174  175  176  177  178  179  180  181  182  183  184  185  186  187 
   2   28   14   23   10   17   11    7    5   12   12    9   37   22 
 188  189  190  191  192  193  194  195  196  197  198  199  200  201 
  14    3    5    6   10    7    2    8    4    7   21    8   14   18 
 202  203  204  205  206  207  208  209  210  211  212  213  214  215 
  28    3   15   14    3    5   22    4    1    5    8    4   14   21 
 216  217  218  219  220  221  222  223  224  225  226  227  228  229 
   6    3    2   12   24   28   38    3   10   10    4   20   25    3 
 230  231  232  233  234  235  236  237  238  239  240  241  242  243 
  10   15    3   14   13   37   10    2   21   10   31   24    8    8 
 244  245  246  247  248  249  250  251  252  253  254  255  256  257 
  11   11    3   14   13   20    6   24    8   23   18   15   15   13 
 258  259  260  261  262  263  264  265  266  267  268  269  270  271 
   7    4    7   11   14    5   26   13    3   27   34   15    1   19 
 272  273  274  275  276  277  278  279  280  281  282  283  284  285 
  34   55   19   19   24   17   58   12   54   29   31   24   33   27 
 286  287  288  289  290  291  292  293  294  295  296  297  298  299 
  11   62   51   29   21   33   71   39   14   43    8   20   30   25 
 300  301  302  303  304  305  306  307  308  309  310  311  312  313 
  21   23   34   21   31   32   22   12   19    4   13   11   11   24 
 314  315  316  317  318  319  320  321  322  323  324  325  326  327 
   7   26   18   14   43   23   19   24   26   24   39   21   19   42 
 328  329  330  331  332  333  334  335  336  337  338  339  340  341 
  24   23   23   31   12   19   27   34    3   27   35   25   21   42 
 342  343  344  345  346  347  348  349  350  351  352  353  354  355 
   6   28   19   18   12   28   10   41   20   23   32   10   34   30 
 356  357  358  359  360  361  362  363  364  365  366  367  368  369 
  20    6   20   18   43   24    7   12   43   12   42   32   10   36 
 370  371  372  373  374  375  376  377  378  379  380  381  382  383 
   4   31   18   17   45   19   37   35   10   24   14   13   23   17 
 384  385  386  387  388  389  390  391  392  393  394  395  396  397 
   4   35   32   31   22   16   40   15   16   16   20   22   23   31 
 398  399  400  401  402  403  404  405  406  407  408  409  410  411 
  19   12   27   21   24   18   32    8   16   16   23    3   23   18 
 412  413  414  415  416  417  418  419  420  421  422  423  424  425 
  26   22    9   26   16   14   13   66   20   12   13   82   14   19 
 426  427  428  429  430  431  432  433  434  435  436  437  438  439 
  25   23   30   26    9   29   18   29   32   20   35   12   25   21 
 440  441  442  443  444  445  446  447  448  449  450  451  452  453 
  14   27   11   10    1   28   10   13   27   24   15   11   35   26 
 454  455  456  457  458  459  460  461  462  463  464  465  466  467 
  11   24   21   17   58   33    3   15   17    6   31   15    7   20 
 468  469  470  471  472  473  474  475  476  477  478  479  480  481 
  28    6   19   21    9   19   23    8   24   18   33   30   25   20 
 482  483  484  485  486  487  488  489  490  491  492  493  494  495 
   9    9    8   23   15   16   15   10   34    8    4   18   11   20 
 496  497  498  499  500  501  502  503  504  505  506  507  508  509 
   5   19    6    8   10    5    4   26   17   22   10   48   18    6 
 510  511  512  513  514  515  516  517  518  519  520  521  522  523 
  24   34   21   34    1   13   14    4    7    7    7    4    9   18 
 524  525  526  527  528  529  530  531  532  533  534  535  536  537 
  11   10    8   10    7   50   21   14   20   12   10   17   21    7 
 538  539  540  541  542  543  544  545  546  547  548  549  550  551 
   3    9    4    6    3   16   24   15   11    5    8   13    8   18 
 552  553  554  555  556  557  558  559  560  561  562  563  564  565 
   8    9    5   12    3   11   18   22   14    7    5   21   10   15 
 566  567  568  569  570  571  572  573  574  575  576  577  578  579 
  33   17   22   15   12   17    7    8   21   14   42    4   27   11 
 580  582  583  584  585  586  587  588  589  590  591  592  593  594 
  13   12   10   16    7   21   12    5   12   31   18   23    8   13 
 595  596  597  598  599  600  601  602  603  604  605  606  607  608 
  13   13   24   12    8   17   10    6   12   18   10    8   18   11 
 609  610  611  612  613  614  615  616  617  618  619  620  621  622 
  12   14   29   22    2    9   10    7   27   26   12    4   10    1 
 623  624  625  626  627  628  629  630  631  632  633  634  635  636 
   2   26    7   14   21   16    5    5    7    4    3   22    4   13 
 637  638  639  640  641  642  643  644  645  646  647  648  649  650 
  19   24    5    8    5   17    9    7   14    3   33   10    5   14 
 651  652  653  654  655  656  657  658  659  660  661  662  664  666 
   5   39    9    5   10   10    5    4    2   11   21    4   18    3 
 667  668  669  670  671  672  673  674  675  676  677  678  679  680 
   2    4   17   14   15    5    9    3    9   22    6   12   13   14 
 681  682  683  684  686  687  688  689  690  691  692  693  694  695 
   8    7    5   30   27    4   34    1   19   20    5    8   22    9 
 696  697  698  699  701  702  703  704  705  706  707  708  709  710 
   6   16   17   14    6   10    7   10   14   26    6   14    2    7 
 711  712  713  714  715  716  717  718  719  720  721  722  723  724 
   6    9    4    2   31   11    9   13    7   33   33    5   14   11 
 725  726  728  729  730  731  732  733  734  735  736  737  738  739 
   2    4    7    2    5    2   26    2   10    1   12    1    5    2 
 740  741  742  743  744  745  746  747  748  749  750  751  752  753 
   1   13    8   11   16    2    8   23   13   16   18    8    6   26 
 754  755  756  757  758  759  760  761  762  763  764  765  766  767 
   6   24   11   12    4   15    5   27   11    3    1   11    7    6 
 768  769  770  771  772  773  774  775  776  777  778  779  780  781 
   4   18   27   31    3   23   21    6    5   17   12   19   19   17 
 782  783  784  785  786  787  788  789  790  791  792  793  794  795 
  26    9   10   34   16   16   13    7    4   14   15   21   13    9 
 796  797  798  799  800  801  802  803  804  805  806  807  808  809 
   3   17   19    9    4    9   46   14   11    1    6   12   31    9 
 810  811  812  813  814  815  816  817  818  819  820  821  822  823 
  21   10   19   36    2   48    4   11   16    6    5    3   46   20 
 824  825  826  827  828  829  830  831  832  833  834  835  836  837 
  31    8   18    8   39   11    6    4    1   14   10    9   24   30 
 838  839  840  841  842  843  844  845  846  847  848  849  850  851 
  14    6   30   11   17    7    9   12    8   12   10   16   13   13 
 852  853  854  855  856  857  858  859  860  861  862  863  864  865 
  19   21   33   16   12    4    4   12   16    3    9   20   16    6 
 866  867  868  869  870  871  872  873  874  875  876  877  878  879 
  11   11   31    5   18   13   15    3    2    5    4    2   19    7 
 880  881  882  883  884  885  886  887  888  889  890  891  892  893 
  11    5    5   12   11    5    3   10   10    4    3   28   21   17 
 894  895  896  897  898  899  900  901  902  903  904  905  906  907 
   3    3    9    1    6   10   11   24    5   13   12    5   38   11 
 908  909  910  911  912  913  914  915  917  918  919  920  921  922 
   4    6    3    4   11   14    2    8    4    6    4   19    4   12 
 923  924  925  926  927  928  929  930  931  932  933  934  935  936 
  30   23    8    5    3    5    2   18    2   11    6   17    4    1 
 938  939  940  941  942  943  944  945  946  950  951  952  953  954 
  13   16   15    3    3   22    8    3    3    4    4    6    4   21 
 955  956  958  961  962  964  965  966  967  968  969  970  971  974 
   5    9    1    2    7    2    5    7   10    1    8   29   10    5 
 975  976  978  979  980  981  982  983  984  985  986  987  988  989 
  10    3    9    3   22    1    1   11   31    5   11    5    4    1 
 990  992  993  994  995  996  997  998  999 1000 1001 1002 1003 1005 
   2   24    6    1    5    1    2    5    4    6    1    8    5   20 
1008 1009 1010 1011 1012 1013 1014 1015 1018 1019 1020 1021 1022 1023 
   5    8   20    5    8    5    5    1   13    3   12   24   17    2 
1024 1025 1026 1027 1029 1030 1032 1033 1034 1035 1036 1037 1039 1041 
   8   16    9   11    7    4   13    4    2    3   29    6   14    6 
1043 1045 1046 1047 1048 1049 1050 1051 1053 1054 1055 1057 1059 1060 
  13    7    6    2    7    9    3   11    5    6   25    2    1   31 
1061 1062 1065 1066 1067 1068 1069 1070 1073 1074 1075 1080 1081 1084 
  14    1    3    7    5    1    8    9    3    6    2    1    9    5 
1086 1087 1088 1089 1092 1093 1094 1095 1096 1097 1098 1100 1103 1104 
  15    1    6    3    2    6   12    3    7   17    8   10    8    8 
1108 1111 1113 1114 1117 1118 1120 1122 1123 1124 1125 1127 1131 1133 
   3    5    2    4   21   20    5    6    9    6    4   12    8    1 
1135 1137 1138 1139 1140 1141 1143 1144 1145 1146 1147 1148 1149 1151 
  33    2    7    9    6    5   15   12   15    5   12    2   15    8 
1152 1153 1154 1156 1157 1158 1160 1161 1162 1163 1164 1165 1166 1167 
  11    2    7   21    6    8    1    9    7   14   10    3    9    2 
1168 1170 1171 1172 1173 1174 1175 1176 1177 1179 1180 1181 1182 1183 
  10   15    4   41   14    5   13   10   12   14   13   12    2    3 
1185 1186 1187 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 
   7    2    1   11    6   14    2    9   10    8    1    2   12    2 
1200 1201 1203 1204 1205 1206 1207 1208 1210 1213 1214 1216 1217 1218 
  20    1   10   18    6    5    4   13    4    5    8   16    3   11 
1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1234 1235 
   2   19   45    5   41    2    7   14   14    9    6   15   11    4 
1236 1237 1238 1239 1240 1241 1242 1244 1245 1246 1247 1248 1250 1254 
   7   31   13   14    7    1    5    4    8   14   11    3    1    1 
1255 1256 1258 1259 1263 1264 1266 1267 1268 1269 1270 1271 1272 1273 
   3   12    3    1    6    6    1    7    3    6    7    6    5   14 
1274 1275 1279 1281 1282 1283 1284 1286 1287 1288 1289 1291 1292 1294 
   2   12   10   10    3   16    2   14    1    1    3   10    9    4 
1295 1296 1297 1302 1304 1305 1307 1308 1309 1310 1311 1312 1313 1314 
   4    5    4   14    3    4    3    7    8   18    1    8    6   30 
1315 1316 1317 1319 1322 1324 1325 1327 1328 1330 1331 1333 1334 1335 
   1    1   14    7   17    3    5    4    2   10    2   17    3    1 
1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 
  10    5   14    8    7   27    1    1    9   12   13   18    3   18 
1351 1352 1353 1357 1358 1362 1363 1365 1368 1369 1370 1372 1373 1374 
   6   11   13    8    8   21    8    8   17   11    2    6    1   12 
1376 1377 1378 1379 1381 1382 1383 1384 1385 1386 1387 1390 1391 1392 
  10    3   12    5    6    5   24   10    6    4   10    8   12    5 
1394 1396 1397 1399 1400 1401 1403 1406 1407 1408 1410 1413 1414 1416 
   6    6   21    8    2    6    7   15    6    2   14    4    1   20 
1417 1421 1422 1423 1425 1426 1429 1431 1432 1434 1435 1437 1440 1442 
   4   18    1    1    2    3    1    2    2    1    1    1   11    2 
1445 1447 1452 1454 1458 1460 1461 1465 1466 1467 1468 1472 1473 1474 
  19    2   10    2    8   11    1    2    3    1    4    1    1    2 
1475 1476 1477 1479 1480 1481 1486 1488 1492 1493 1494 1495 1496 1497 
   5    1    2    1    2    2    1   19    4    3    1    4    4    1 
1498 1499 1500 1502 1507 1519 1526 1527 1528 1531 1534 1536 1540 1543 
  12    1    1    8    1    2    3    2    3    6    6    6    4    4 
1548 1549 1551 1552 1553 1561 1564 1565 1567 1569 1573 1577 1580 1583 
   2    3    2    1    7    4    2    3    3   12    2    1    2    4 
1587 1588 1593 1597 1598 1603 1604 1608 1617 1618 1624 1626 1637 1638 
   1    8    4    3    6    1    1    9    3    1    1    3    2   16 
1647 1654 1655 1676 1685 1695 1701 1705 1728 1734 1738 1743 1745 1752 
   1    3    4    1    1    1    1    5    1    1    3    1    4    3 
1758 1765 1771 1774 1775 1800 1808 1811 1817 1852 1875 1882 1922 1951 
   2    3    4    4    1    4    5    4    1    3    3    1    2    5 
1965 
   4 
3 least connected regions:
3093 4752 5564 with 2 links
4 most connected regions:
3260 8169 12559 13540 with 1965 links

Next, nb2listw() of spdep packge will be used to convert the output neighbours lists (i.e. nb) into a spatial weights.

nb_lw <- nb2listw(nb, style = 'W')
summary(nb_lw)
Characteristics of weights list object:
Neighbour list object:
Number of regions: 15901 
Number of nonzero links: 10219360 
Percentage nonzero weights: 4.0418 
Average number of links: 642.6866 
Link number distribution:

   2    7   14   25   26   31   32   46   56   57   60   65   68   69 
   3    1   14   15    5    4    2   47    4    4    5    2    4    1 
  71   72   75   79   86   88   89   90   97   99  101  103  106  109 
  12    1    1   78    3    5    4    3    8    8    6    2    2    5 
 110  112  115  117  118  119  120  121  122  123  124  125  126  128 
   8    3    6    1    9    6    5    7    4   22    7   55   21   30 
 130  131  132  133  134  135  136  137  138  139  140  141  142  143 
   1   14    6   14    7    5    5    9    2   28    4    2    8   15 
 145  146  147  148  149  150  151  152  153  154  155  156  157  158 
   9    6   17    6    1    1   21   20   13    7    3    8    9    5 
 159  160  161  162  163  164  165  166  167  168  169  170  171  173 
  17    6    3    2   12    6    6    3   11    3   11    3    8   14 
 174  175  176  177  178  179  180  181  182  183  184  185  186  187 
   2   28   14   23   10   17   11    7    5   12   12    9   37   22 
 188  189  190  191  192  193  194  195  196  197  198  199  200  201 
  14    3    5    6   10    7    2    8    4    7   21    8   14   18 
 202  203  204  205  206  207  208  209  210  211  212  213  214  215 
  28    3   15   14    3    5   22    4    1    5    8    4   14   21 
 216  217  218  219  220  221  222  223  224  225  226  227  228  229 
   6    3    2   12   24   28   38    3   10   10    4   20   25    3 
 230  231  232  233  234  235  236  237  238  239  240  241  242  243 
  10   15    3   14   13   37   10    2   21   10   31   24    8    8 
 244  245  246  247  248  249  250  251  252  253  254  255  256  257 
  11   11    3   14   13   20    6   24    8   23   18   15   15   13 
 258  259  260  261  262  263  264  265  266  267  268  269  270  271 
   7    4    7   11   14    5   26   13    3   27   34   15    1   19 
 272  273  274  275  276  277  278  279  280  281  282  283  284  285 
  34   55   19   19   24   17   58   12   54   29   31   24   33   27 
 286  287  288  289  290  291  292  293  294  295  296  297  298  299 
  11   62   51   29   21   33   71   39   14   43    8   20   30   25 
 300  301  302  303  304  305  306  307  308  309  310  311  312  313 
  21   23   34   21   31   32   22   12   19    4   13   11   11   24 
 314  315  316  317  318  319  320  321  322  323  324  325  326  327 
   7   26   18   14   43   23   19   24   26   24   39   21   19   42 
 328  329  330  331  332  333  334  335  336  337  338  339  340  341 
  24   23   23   31   12   19   27   34    3   27   35   25   21   42 
 342  343  344  345  346  347  348  349  350  351  352  353  354  355 
   6   28   19   18   12   28   10   41   20   23   32   10   34   30 
 356  357  358  359  360  361  362  363  364  365  366  367  368  369 
  20    6   20   18   43   24    7   12   43   12   42   32   10   36 
 370  371  372  373  374  375  376  377  378  379  380  381  382  383 
   4   31   18   17   45   19   37   35   10   24   14   13   23   17 
 384  385  386  387  388  389  390  391  392  393  394  395  396  397 
   4   35   32   31   22   16   40   15   16   16   20   22   23   31 
 398  399  400  401  402  403  404  405  406  407  408  409  410  411 
  19   12   27   21   24   18   32    8   16   16   23    3   23   18 
 412  413  414  415  416  417  418  419  420  421  422  423  424  425 
  26   22    9   26   16   14   13   66   20   12   13   82   14   19 
 426  427  428  429  430  431  432  433  434  435  436  437  438  439 
  25   23   30   26    9   29   18   29   32   20   35   12   25   21 
 440  441  442  443  444  445  446  447  448  449  450  451  452  453 
  14   27   11   10    1   28   10   13   27   24   15   11   35   26 
 454  455  456  457  458  459  460  461  462  463  464  465  466  467 
  11   24   21   17   58   33    3   15   17    6   31   15    7   20 
 468  469  470  471  472  473  474  475  476  477  478  479  480  481 
  28    6   19   21    9   19   23    8   24   18   33   30   25   20 
 482  483  484  485  486  487  488  489  490  491  492  493  494  495 
   9    9    8   23   15   16   15   10   34    8    4   18   11   20 
 496  497  498  499  500  501  502  503  504  505  506  507  508  509 
   5   19    6    8   10    5    4   26   17   22   10   48   18    6 
 510  511  512  513  514  515  516  517  518  519  520  521  522  523 
  24   34   21   34    1   13   14    4    7    7    7    4    9   18 
 524  525  526  527  528  529  530  531  532  533  534  535  536  537 
  11   10    8   10    7   50   21   14   20   12   10   17   21    7 
 538  539  540  541  542  543  544  545  546  547  548  549  550  551 
   3    9    4    6    3   16   24   15   11    5    8   13    8   18 
 552  553  554  555  556  557  558  559  560  561  562  563  564  565 
   8    9    5   12    3   11   18   22   14    7    5   21   10   15 
 566  567  568  569  570  571  572  573  574  575  576  577  578  579 
  33   17   22   15   12   17    7    8   21   14   42    4   27   11 
 580  582  583  584  585  586  587  588  589  590  591  592  593  594 
  13   12   10   16    7   21   12    5   12   31   18   23    8   13 
 595  596  597  598  599  600  601  602  603  604  605  606  607  608 
  13   13   24   12    8   17   10    6   12   18   10    8   18   11 
 609  610  611  612  613  614  615  616  617  618  619  620  621  622 
  12   14   29   22    2    9   10    7   27   26   12    4   10    1 
 623  624  625  626  627  628  629  630  631  632  633  634  635  636 
   2   26    7   14   21   16    5    5    7    4    3   22    4   13 
 637  638  639  640  641  642  643  644  645  646  647  648  649  650 
  19   24    5    8    5   17    9    7   14    3   33   10    5   14 
 651  652  653  654  655  656  657  658  659  660  661  662  664  666 
   5   39    9    5   10   10    5    4    2   11   21    4   18    3 
 667  668  669  670  671  672  673  674  675  676  677  678  679  680 
   2    4   17   14   15    5    9    3    9   22    6   12   13   14 
 681  682  683  684  686  687  688  689  690  691  692  693  694  695 
   8    7    5   30   27    4   34    1   19   20    5    8   22    9 
 696  697  698  699  701  702  703  704  705  706  707  708  709  710 
   6   16   17   14    6   10    7   10   14   26    6   14    2    7 
 711  712  713  714  715  716  717  718  719  720  721  722  723  724 
   6    9    4    2   31   11    9   13    7   33   33    5   14   11 
 725  726  728  729  730  731  732  733  734  735  736  737  738  739 
   2    4    7    2    5    2   26    2   10    1   12    1    5    2 
 740  741  742  743  744  745  746  747  748  749  750  751  752  753 
   1   13    8   11   16    2    8   23   13   16   18    8    6   26 
 754  755  756  757  758  759  760  761  762  763  764  765  766  767 
   6   24   11   12    4   15    5   27   11    3    1   11    7    6 
 768  769  770  771  772  773  774  775  776  777  778  779  780  781 
   4   18   27   31    3   23   21    6    5   17   12   19   19   17 
 782  783  784  785  786  787  788  789  790  791  792  793  794  795 
  26    9   10   34   16   16   13    7    4   14   15   21   13    9 
 796  797  798  799  800  801  802  803  804  805  806  807  808  809 
   3   17   19    9    4    9   46   14   11    1    6   12   31    9 
 810  811  812  813  814  815  816  817  818  819  820  821  822  823 
  21   10   19   36    2   48    4   11   16    6    5    3   46   20 
 824  825  826  827  828  829  830  831  832  833  834  835  836  837 
  31    8   18    8   39   11    6    4    1   14   10    9   24   30 
 838  839  840  841  842  843  844  845  846  847  848  849  850  851 
  14    6   30   11   17    7    9   12    8   12   10   16   13   13 
 852  853  854  855  856  857  858  859  860  861  862  863  864  865 
  19   21   33   16   12    4    4   12   16    3    9   20   16    6 
 866  867  868  869  870  871  872  873  874  875  876  877  878  879 
  11   11   31    5   18   13   15    3    2    5    4    2   19    7 
 880  881  882  883  884  885  886  887  888  889  890  891  892  893 
  11    5    5   12   11    5    3   10   10    4    3   28   21   17 
 894  895  896  897  898  899  900  901  902  903  904  905  906  907 
   3    3    9    1    6   10   11   24    5   13   12    5   38   11 
 908  909  910  911  912  913  914  915  917  918  919  920  921  922 
   4    6    3    4   11   14    2    8    4    6    4   19    4   12 
 923  924  925  926  927  928  929  930  931  932  933  934  935  936 
  30   23    8    5    3    5    2   18    2   11    6   17    4    1 
 938  939  940  941  942  943  944  945  946  950  951  952  953  954 
  13   16   15    3    3   22    8    3    3    4    4    6    4   21 
 955  956  958  961  962  964  965  966  967  968  969  970  971  974 
   5    9    1    2    7    2    5    7   10    1    8   29   10    5 
 975  976  978  979  980  981  982  983  984  985  986  987  988  989 
  10    3    9    3   22    1    1   11   31    5   11    5    4    1 
 990  992  993  994  995  996  997  998  999 1000 1001 1002 1003 1005 
   2   24    6    1    5    1    2    5    4    6    1    8    5   20 
1008 1009 1010 1011 1012 1013 1014 1015 1018 1019 1020 1021 1022 1023 
   5    8   20    5    8    5    5    1   13    3   12   24   17    2 
1024 1025 1026 1027 1029 1030 1032 1033 1034 1035 1036 1037 1039 1041 
   8   16    9   11    7    4   13    4    2    3   29    6   14    6 
1043 1045 1046 1047 1048 1049 1050 1051 1053 1054 1055 1057 1059 1060 
  13    7    6    2    7    9    3   11    5    6   25    2    1   31 
1061 1062 1065 1066 1067 1068 1069 1070 1073 1074 1075 1080 1081 1084 
  14    1    3    7    5    1    8    9    3    6    2    1    9    5 
1086 1087 1088 1089 1092 1093 1094 1095 1096 1097 1098 1100 1103 1104 
  15    1    6    3    2    6   12    3    7   17    8   10    8    8 
1108 1111 1113 1114 1117 1118 1120 1122 1123 1124 1125 1127 1131 1133 
   3    5    2    4   21   20    5    6    9    6    4   12    8    1 
1135 1137 1138 1139 1140 1141 1143 1144 1145 1146 1147 1148 1149 1151 
  33    2    7    9    6    5   15   12   15    5   12    2   15    8 
1152 1153 1154 1156 1157 1158 1160 1161 1162 1163 1164 1165 1166 1167 
  11    2    7   21    6    8    1    9    7   14   10    3    9    2 
1168 1170 1171 1172 1173 1174 1175 1176 1177 1179 1180 1181 1182 1183 
  10   15    4   41   14    5   13   10   12   14   13   12    2    3 
1185 1186 1187 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 
   7    2    1   11    6   14    2    9   10    8    1    2   12    2 
1200 1201 1203 1204 1205 1206 1207 1208 1210 1213 1214 1216 1217 1218 
  20    1   10   18    6    5    4   13    4    5    8   16    3   11 
1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1234 1235 
   2   19   45    5   41    2    7   14   14    9    6   15   11    4 
1236 1237 1238 1239 1240 1241 1242 1244 1245 1246 1247 1248 1250 1254 
   7   31   13   14    7    1    5    4    8   14   11    3    1    1 
1255 1256 1258 1259 1263 1264 1266 1267 1268 1269 1270 1271 1272 1273 
   3   12    3    1    6    6    1    7    3    6    7    6    5   14 
1274 1275 1279 1281 1282 1283 1284 1286 1287 1288 1289 1291 1292 1294 
   2   12   10   10    3   16    2   14    1    1    3   10    9    4 
1295 1296 1297 1302 1304 1305 1307 1308 1309 1310 1311 1312 1313 1314 
   4    5    4   14    3    4    3    7    8   18    1    8    6   30 
1315 1316 1317 1319 1322 1324 1325 1327 1328 1330 1331 1333 1334 1335 
   1    1   14    7   17    3    5    4    2   10    2   17    3    1 
1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 
  10    5   14    8    7   27    1    1    9   12   13   18    3   18 
1351 1352 1353 1357 1358 1362 1363 1365 1368 1369 1370 1372 1373 1374 
   6   11   13    8    8   21    8    8   17   11    2    6    1   12 
1376 1377 1378 1379 1381 1382 1383 1384 1385 1386 1387 1390 1391 1392 
  10    3   12    5    6    5   24   10    6    4   10    8   12    5 
1394 1396 1397 1399 1400 1401 1403 1406 1407 1408 1410 1413 1414 1416 
   6    6   21    8    2    6    7   15    6    2   14    4    1   20 
1417 1421 1422 1423 1425 1426 1429 1431 1432 1434 1435 1437 1440 1442 
   4   18    1    1    2    3    1    2    2    1    1    1   11    2 
1445 1447 1452 1454 1458 1460 1461 1465 1466 1467 1468 1472 1473 1474 
  19    2   10    2    8   11    1    2    3    1    4    1    1    2 
1475 1476 1477 1479 1480 1481 1486 1488 1492 1493 1494 1495 1496 1497 
   5    1    2    1    2    2    1   19    4    3    1    4    4    1 
1498 1499 1500 1502 1507 1519 1526 1527 1528 1531 1534 1536 1540 1543 
  12    1    1    8    1    2    3    2    3    6    6    6    4    4 
1548 1549 1551 1552 1553 1561 1564 1565 1567 1569 1573 1577 1580 1583 
   2    3    2    1    7    4    2    3    3   12    2    1    2    4 
1587 1588 1593 1597 1598 1603 1604 1608 1617 1618 1624 1626 1637 1638 
   1    8    4    3    6    1    1    9    3    1    1    3    2   16 
1647 1654 1655 1676 1685 1695 1701 1705 1728 1734 1738 1743 1745 1752 
   1    3    4    1    1    1    1    5    1    1    3    1    4    3 
1758 1765 1771 1774 1775 1800 1808 1811 1817 1852 1875 1882 1922 1951 
   2    3    4    4    1    4    5    4    1    3    3    1    2    5 
1965 
   4 
3 least connected regions:
3093 4752 5564 with 2 links
4 most connected regions:
3260 8169 12559 13540 with 1965 links

Weights style: W 
Weights constants summary:
      n        nn    S0      S1       S2
W 15901 252841801 15901 79.6504 64104.78

Next, lm.morantest() of spdep package will be used to perform Moran’s I test for residual spatial autocorrelation

lm.morantest(resale_tbl.mlr1, nb_lw)

    Global Moran I for regression residuals

data:  
model: lm(formula = resale_price ~ remaininglease_years +
floor_area_sqm + prx_to_hawker + prx_to_trainStn +
prx_to_supermarket, data = resale_3414)
weights: nb_lw

Moran I statistic standard deviate = 1249.4, p-value < 2.2e-16
alternative hypothesis: greater
sample estimates:
Observed Moran I      Expectation         Variance 
    6.709842e-01    -1.777304e-04     2.885511e-07 

Based on the global moran’s I test, the residual spatial autocorrelation shows that it’s p-value is less than 2.2 x 10^-16, which is a significantly small value, and is much lower than the alpha value of 0.05, hence we will reject the null hypothesis that the residuals are randomly distribute, in other words, the residuals resembles cluster distributions.

Building Hedonic Pricing Models using GWmodel

In this section, we will learn how to model hedonic pricing using both the fixed and adaptive bandwidth schemes

Building Adaptive Bandwidth GWR Model

In this section, we will calibrate the gwr-absed hedonic pricing model by using adaptive bandwidth approach.

Computing the adaptive bandwidth

We will be using bw.ger() to determine the recommended data point to use.

The code chunk used look very similar to the one used to compute the fixed bandwidth except the adaptive argument has changed to TRUE.

bw.adaptive <- bw.gwr(formula = resale_price ~ remaininglease_years + floor_area_sqm + prx_to_hawker + prx_to_trainStn  + prx_to_supermarket, data=resale_tbl.sp, approach="CV", kernel="gaussian",
adaptive=TRUE, longlat=FALSE)
Take a cup of tea and have a break, it will take a few minutes.
          -----A kind suggestion from GWmodel development group
Adaptive bandwidth: 9834 CV score: 1.477862e+14 
Adaptive bandwidth: 6086 CV score: 1.343193e+14 
Adaptive bandwidth: 3767 CV score: 1.168869e+14 
Adaptive bandwidth: 2337 CV score: 9.445512e+13 
Adaptive bandwidth: 1449 CV score: 6.53688e+13 
Adaptive bandwidth: 905 CV score: 4.59035e+13 
Adaptive bandwidth: 563 CV score: 3.621509e+13 
Adaptive bandwidth: 358 CV score: 3.051304e+13 
Adaptive bandwidth: 224 CV score: 2.639004e+13 
Adaptive bandwidth: 149 CV score: 2.362456e+13 
Adaptive bandwidth: 94 CV score: 2.043158e+13 
Adaptive bandwidth: 69 CV score: 1.824158e+13 
Adaptive bandwidth: 44 CV score: 1.670637e+13 
Adaptive bandwidth: 38 CV score: 1.635281e+13 
Adaptive bandwidth: 25 CV score: NaN 
Adaptive bandwidth: 37 CV score: 1.630511e+13 
Adaptive bandwidth: 45 CV score: 1.674146e+13 
Adaptive bandwidth: 40 CV score: 1.651203e+13 
Adaptive bandwidth: 43 CV score: 1.664289e+13 
Adaptive bandwidth: 41 CV score: 1.654087e+13 
Adaptive bandwidth: 42 CV score: 1.660254e+13 
Adaptive bandwidth: 41 CV score: 1.654087e+13 
Adaptive bandwidth: 41 CV score: 1.654087e+13 
Adaptive bandwidth: 40 CV score: 1.651203e+13 
Adaptive bandwidth: 40 CV score: 1.651203e+13 
Adaptive bandwidth: 39 CV score: 1.643857e+13 
Adaptive bandwidth: 39 CV score: 1.643857e+13 
Adaptive bandwidth: 38 CV score: 1.635281e+13 
Adaptive bandwidth: 38 CV score: 1.635281e+13 
Adaptive bandwidth: 37 CV score: 1.630511e+13 

Constructing the adaptive bandwidth gwr model

Now, we can calibrate the gwr-based hedonic pricing model by using adaptive bandwidth and gaussian kernel.

gwr.adaptive <- gwr.basic(formula = resale_price ~ remaininglease_years + floor_area_sqm + prx_to_hawker + prx_to_trainStn  + prx_to_supermarket, data=resale_tbl.sp, bw=bw.adaptive, kernel = 'gaussian', adaptive=TRUE, longlat = FALSE)
gwr.adaptive
   ***********************************************************************
   *                       Package   GWmodel                             *
   ***********************************************************************
   Program starts at: 2021-11-08 01:38:11 
   Call:
   gwr.basic(formula = resale_price ~ remaininglease_years + floor_area_sqm + 
    prx_to_hawker + prx_to_trainStn + prx_to_supermarket, data = resale_tbl.sp, 
    bw = bw.adaptive, kernel = "gaussian", adaptive = TRUE, longlat = FALSE)

   Dependent (y) variable:  resale_price
   Independent variables:  remaininglease_years floor_area_sqm prx_to_hawker prx_to_trainStn prx_to_supermarket
   Number of data points: 15901
   ***********************************************************************
   *                    Results of Global Regression                     *
   ***********************************************************************

   Call:
    lm(formula = formula, data = data)

   Residuals:
    Min      1Q  Median      3Q     Max 
-197734  -72129  -21800   40093  674299 

   Coefficients:
                          Estimate Std. Error t value Pr(>|t|)    
   (Intercept)          142448.724  13641.365  10.442   <2e-16 ***
   remaininglease_years   3262.077     67.428  48.379   <2e-16 ***
   floor_area_sqm         1371.204    121.416  11.293   <2e-16 ***
   prx_to_hawker           -68.919      1.649 -41.793   <2e-16 ***
   prx_to_trainStn         -47.719      2.199 -21.697   <2e-16 ***
   prx_to_supermarket      -45.747      5.453  -8.389   <2e-16 ***

   ---Significance stars
   Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 
   Residual standard error: 104400 on 15895 degrees of freedom
   Multiple R-squared: 0.2455
   Adjusted R-squared: 0.2452 
   F-statistic:  1034 on 5 and 15895 DF,  p-value: < 2.2e-16 
   ***Extra Diagnostic information
   Residual sum of squares: 1.73102e+14
   Sigma(hat): 104343.7
   AIC:  412623.4
   AICc:  412623.4
   BIC:  396843.8
   ***********************************************************************
   *          Results of Geographically Weighted Regression              *
   ***********************************************************************

   *********************Model calibration information*********************
   Kernel function: gaussian 
   Adaptive bandwidth: 37 (number of nearest neighbours)
   Regression points: the same locations as observations are used.
   Distance metric: Euclidean distance metric is used.

   ****************Summary of GWR coefficient estimates:******************
                               Min.     1st Qu.      Median
   Intercept            -8.0380e+06 -3.3711e+05 -1.4016e+05
   remaininglease_years -2.4751e+04  2.8060e+03  4.7909e+03
   floor_area_sqm       -6.4602e+04  1.2782e+03  2.3993e+03
   prx_to_hawker        -1.3557e+04 -5.8342e+01 -1.1777e+01
   prx_to_trainStn      -1.9680e+04 -1.1515e+02 -5.2786e+01
   prx_to_supermarket   -9.0354e+03 -5.7309e+01 -4.8764e+00
                            3rd Qu.      Max.
   Intercept             4.6656e+04 7205778.9
   remaininglease_years  7.4232e+03   34021.4
   floor_area_sqm        3.9606e+03   83281.6
   prx_to_hawker         3.8928e+01   19716.8
   prx_to_trainStn       7.5668e+00    8330.9
   prx_to_supermarket    6.0173e+01   12804.5
   ************************Diagnostic information*************************
   Number of data points: 15901 
   Effective number of parameters (2trace(S) - trace(S'S)): 1260.266 
   Effective degrees of freedom (n-2trace(S) + trace(S'S)): 14640.73 
   AICc (GWR book, Fotheringham, et al. 2002, p. 61, eq 2.33): 374822.7 
   AIC (GWR book, Fotheringham, et al. 2002,GWR p. 96, eq. 4.22): 373692.7 
   BIC (GWR book, Fotheringham, et al. 2002,GWR p. 61, eq. 2.34): 366420.6 
   Residual sum of squares: 1.406777e+13 
   R-square value:  0.9386808 
   Adjusted R-square value:  0.9334022 

   ***********************************************************************
   Program stops at: 2021-11-08 01:39:38 

The report shows that the adjusted r-square of the gwr is 0.9334022 which is significantly better than the globle multiple linear regression model of 0.2452

Visualizing the GWR output

Converting SDF into sf data.frame

To visualize the fields in SDF object, we need to convert the output into sf data.frame first:

resale_3414.adaptive <- st_as_sf(gwr.adaptive$SDF) %>%
  st_transform(crs=3414)

Setting the projection:

resale_3414.adaptive.svy21 <- st_transform(resale_3414.adaptive, 3414)
resale_3414.adaptive.svy21
Simple feature collection with 15901 features and 24 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 11597.31 ymin: 28217.39 xmax: 42623.63 ymax: 48741.06
Projected CRS: SVY21 / Singapore TM
First 10 features:
   Intercept remaininglease_years floor_area_sqm prx_to_hawker
1  -207463.5             6538.840      3260.5551    -64.202694
2  -255140.0             4973.831      3859.2602    -22.927203
3  -364974.2             9867.826      2702.6791    -16.894435
4  -222610.9             5450.554      2940.9428     73.955393
5  -273052.3             7778.878      2719.0350     32.513526
6  -306878.6             9811.496      2093.7020     -8.119189
7  -168062.9             9507.934       907.8766    -10.846866
8  -231862.1             6553.484      2539.4876     16.434675
9  -146064.9             7404.562      1407.6267    -48.779654
10 -195091.2             6773.747      2318.2551    -56.639485
   prx_to_trainStn prx_to_supermarket      y     yhat   residual
1        -78.48052          38.151408 330000 391939.2 -61939.207
2        -44.31763           9.179556 360000 380727.6 -20727.626
3        -93.43115         -40.205194 370000 386070.4 -16070.373
4        -21.50742         -37.747737 375000 397116.4 -22116.439
5        -72.31413         -27.129082 380000 369549.7  10450.289
6        -93.89983         -38.708983 380000 383196.5  -3196.497
7       -113.60421         -22.648319 385000 408465.2 -23465.245
8        -45.07958          -3.477971 395000 396577.3  -1577.272
9       -101.61087          36.234800 395000 392422.2   2577.759
10       -86.79003          28.585124 395000 368775.3  26224.730
   CV_Score Stud_residual Intercept_SE remaininglease_years_SE
1         0   -2.07973226     73080.86                246.6561
2         0   -0.69180945     64650.37                902.8835
3         0   -0.53743763    126910.41                302.4738
4         0   -0.75838083     60359.59                615.6985
5         0    0.35517176    171040.28                503.3288
6         0   -0.10538078    113181.86                285.7373
7         0   -0.77212792    101654.55                249.4174
8         0   -0.05187776     55551.89                417.6279
9         0    0.08566000     72137.63                870.7458
10        0    0.91583702     67817.51                753.3360
   floor_area_sqm_SE prx_to_hawker_SE prx_to_trainStn_SE
1           759.0503         43.48660           19.61619
2           796.8294         30.47629           17.60026
3          1263.7203         36.49889           13.84860
4           747.9891         29.67857           17.69157
5          1768.4194         43.77430           26.99447
6          1125.6782         30.63433           12.56152
7           997.1059         28.54684           12.97400
8           610.3067         24.87788           15.39005
9           757.7927         30.20387           18.93115
10          703.3059         29.37073           17.67902
   prx_to_supermarket_SE Intercept_TV remaininglease_years_TV
1               50.29069    -2.838821               26.509950
2               13.04208    -3.946458                5.508829
3               36.24447    -2.875841               32.623734
4               17.59150    -3.688079                8.852634
5               36.71177    -1.596421               15.454864
6               31.18278    -2.711376               34.337465
7               24.17994    -1.653274               38.120572
8               11.21603    -4.173794               15.692159
9               13.46584    -2.024809                8.503701
10              12.99317    -2.876708                8.991668
   floor_area_sqm_TV prx_to_hawker_TV prx_to_trainStn_TV
1          4.2955719       -1.4763787          -4.000803
2          4.8432703       -0.7522964          -2.518010
3          2.1386687       -0.4628753          -6.746616
4          3.9317989        2.4918789          -1.215687
5          1.5375510        0.7427537          -2.678850
6          1.8599473       -0.2650356          -7.475196
7          0.9105117       -0.3799673          -8.756301
8          4.1610025        0.6606140          -2.929138
9          1.8575354       -1.6150131          -5.367390
10         3.2962261       -1.9284333          -4.909209
   prx_to_supermarket_TV  Local_R2                  geometry
1              0.7586177 0.8516994 POINT (29179.92 38822.08)
2              0.7038414 0.8031640 POINT (28423.42 39745.94)
3             -1.1092779 0.9663806 POINT (30550.38 39588.77)
4             -2.1457941 0.7857342  POINT (28240.06 39477.6)
5             -0.7389751 0.8751764 POINT (30443.27 38382.85)
6             -1.2413577 0.9626188  POINT (30637.92 39516.9)
7             -0.9366574 0.9474907 POINT (30347.48 38995.85)
8             -0.3100893 0.7930914  POINT (28325.75 39700.7)
9              2.6908687 0.7408476 POINT (28611.87 40270.61)
10             2.2000112 0.7757424 POINT (28271.22 40241.11)
gwr.adaptive.output <- as.data.frame(gwr.adaptive$SDF)
resale_3414.adaptive <- cbind(resale_tbl.res.sf, as.matrix(gwr.adaptive.output))
glimpse(resale_3414.adaptive)
Rows: 15,901
Columns: 46
$ month                   <chr> "2019-01", "2019-01", "2019-01", "20~
$ town                    <chr> "ANG MO KIO", "ANG MO KIO", "ANG MO ~
$ flat_type               <chr> "4 ROOM", "4 ROOM", "4 ROOM", "4 ROO~
$ address                 <chr> "204 ANG MO KIO AVE 3", "175 ANG MO ~
$ block                   <chr> "204", "175", "543", "118", "411", "~
$ street_name             <chr> "ANG MO KIO AVE 3", "ANG MO KIO AVE ~
$ storey_range            <chr> "01 TO 03", "07 TO 09", "01 TO 03", ~
$ floor_area_sqm          <dbl> 92, 91, 92, 99, 92, 92, 92, 92, 93, ~
$ flat_model              <chr> "New Generation", "New Generation", ~
$ lease_commence_date     <dbl> 1977, 1981, 1981, 1978, 1979, 1981, ~
$ remaining_lease         <chr> "57 years", "61 years 06 months", "6~
$ remaininglease_years    <dbl> 57.00, 61.50, 61.08, 58.33, 59.58, 6~
$ resale_price            <dbl> 330000, 360000, 370000, 375000, 3800~
$ prx_to_hawker           <dbl> 441.82653, 269.72560, 258.29513, 436~
$ prx_to_trainStn         <dbl> 703.9715, 403.4297, 889.9529, 200.97~
$ prx_to_supermarket      <dbl> 270.8222, 310.1889, 318.7560, 458.67~
$ log_resale_price        <dbl> 12.70685, 12.79386, 12.82126, 12.834~
$ max_floor               <dbl> 3, 9, 3, 6, 6, 2, 9, 6, 2, 9, 9, 9, ~
$ MLR_RES                 <dbl> -48105.3253, -55815.1851, -22995.642~
$ Intercept               <dbl> -207463.50, -255139.95, -364974.20, ~
$ remaininglease_years.1  <dbl> 6538.840, 4973.831, 9867.826, 5450.5~
$ floor_area_sqm.1        <dbl> 3260.5551, 3859.2602, 2702.6791, 294~
$ prx_to_hawker.1         <dbl> -64.202694, -22.927203, -16.894435, ~
$ prx_to_trainStn.1       <dbl> -78.480516, -44.317628, -93.431150, ~
$ prx_to_supermarket.1    <dbl> 38.1514081, 9.1795557, -40.2051939, ~
$ y                       <dbl> 330000, 360000, 370000, 375000, 3800~
$ yhat                    <dbl> 391939.2, 380727.6, 386070.4, 397116~
$ residual                <dbl> -61939.2068, -20727.6260, -16070.372~
$ CV_Score                <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ~
$ Stud_residual           <dbl> -2.079732263, -0.691809452, -0.53743~
$ Intercept_SE            <dbl> 73080.86, 64650.37, 126910.41, 60359~
$ remaininglease_years_SE <dbl> 246.6561, 902.8835, 302.4738, 615.69~
$ floor_area_sqm_SE       <dbl> 759.0503, 796.8294, 1263.7203, 747.9~
$ prx_to_hawker_SE        <dbl> 43.48660, 30.47629, 36.49889, 29.678~
$ prx_to_trainStn_SE      <dbl> 19.61619, 17.60026, 13.84860, 17.691~
$ prx_to_supermarket_SE   <dbl> 50.29069, 13.04208, 36.24447, 17.591~
$ Intercept_TV            <dbl> -2.8388214, -3.9464580, -2.8758413, ~
$ remaininglease_years_TV <dbl> 26.509950, 5.508829, 32.623734, 8.85~
$ floor_area_sqm_TV       <dbl> 4.2955719, 4.8432703, 2.1386687, 3.9~
$ prx_to_hawker_TV        <dbl> -1.4763787, -0.7522964, -0.4628753, ~
$ prx_to_trainStn_TV      <dbl> -4.0008033, -2.5180100, -6.7466157, ~
$ prx_to_supermarket_TV   <dbl> 0.75861770, 0.70384137, -1.10927791,~
$ Local_R2                <dbl> 0.8516994, 0.8031640, 0.9663806, 0.7~
$ coords.x1               <dbl> 29179.92, 28423.42, 30550.38, 28240.~
$ coords.x2               <dbl> 38822.08, 39745.94, 39588.77, 39477.~
$ geometry                <POINT [m]> POINT (29179.92 38822.08), POI~
summary(gwr.adaptive$SDF$yhat)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
 243002  357292  405871  433674  464960  990135 

Visualising local R2

Interactive display of the point symbols on a map:

tmap_mode("view")
tm_shape(mpsz_3414)+
  tm_polygons(alpha = 0.1) +
tm_shape(resale_3414.adaptive) +  
  tm_dots(col = "Local_R2",
          border.col = "gray60",
          border.lwd = 1) +
  tm_view(set.zoom.limits = c(11,14))

Setting back tmap mode to “plot”

tmap_mode("plot")

By URA Planning Region

tmap_mode("view")
tm_shape(mpsz_3414[mpsz_3414$REGION_N=="CENTRAL REGION", ])+
  tm_polygons()+
tm_shape(resale_3414.adaptive) + 
  tm_bubbles(col = "Local_R2",
           size = 0.15,
           border.col = "gray60",
           border.lwd = 1)

Setting back tmap mode to “plot”

tmap_mode("plot")